/* DList.java */

package graph;

import list.*;
import java.util.Hashtable;
import java.util.Arrays;

/**
 * EdgeList is a high level abstraction of a list of edges.
 * Most edge related queries should done by vertices should be
 * done by this class and not the lower level EdgeListNode.
 */   
class EdgeList extends DList{
  /**
   * Reimplements newNode to return an EdgeListNode;
   * 
   * @param item the item to be insterted. Should be an Edge.
   * @param list the list to be the parent of the new node.
   * @param prev the previous node.
   * @param next the next node.
   */
  protected DListNode newNode(Object item, DList list, DListNode prev, DListNode next) {
    return new EdgeListNode(item, list, prev, next);
  }
  
  /**
   * Returns the Neighbors of this list with reference to an object.
   *
   * @check the object whose neighbors are being found.
   * 
   * @return a Neighbors object with neighbor and weight information.
   */
  public Neighbors getNeighbors(Object check) {
    Neighbors n = new Neighbors();
    n.neighborList = new Object[size];
    n.weightList = new int[size];
    ListNode current = front();
    try {
      for (int i = 0; i < size; ++i) {
	Edge edge = (Edge) current.item();
	n.neighborList[i] = edge.getNeighbor(check);
	n.weightList[i] = edge.weight();
	current = current.next();
      }
    } catch (InvalidNodeException ex) {
      ex.printStackTrace();
    }
      return n;
  }
  
  /**
   * Removes all of the edges from the list, and corresponding parnter edges
   * in other lists.
   */
  
  public void destroy(Hashtable hash) {
    try {
      ListNode current = front();
      while(current.isValidNode()) {
    	  VertexPair vp = ((Edge) current.item()).getVertex();
    	  hash.remove(vp);
    	  ListNode next = current.next();	
    	  current.remove();
    	  current = next;
      }
    } catch(InvalidNodeException ex) {
      ex.printStackTrace();
    }
  }
      
  public static void main(String[] args) {
    try {
      EdgeList list1 = new EdgeList();
      EdgeList list2 = new EdgeList();
      EdgeList list3 = new EdgeList();
      Edge e12 = new Edge(new VertexPair(new Integer(1), new Integer(2)), 12);
      Edge e13 = new Edge(new VertexPair(new Integer(1), new Integer(3)), 13);
      Edge e23 = new Edge(new VertexPair(new Integer(2), new Integer(3)), 23);
      Edge e33 = new Edge(new VertexPair(new Integer(3), new Integer(3)), 33);
      Edge e14 = new Edge(new VertexPair(new Integer(1), new Integer(4)), 14);
      Edge e15 = new Edge(new VertexPair(new Integer(1), new Integer(5)), 15);
      list1.insertFront(e12);
      list2.insertFront(e12);
      EdgeListNode node12 = (EdgeListNode) list1.front();
      node12.setPartner((EdgeListNode) list2.front());
      list1.insertFront(e13);
      list3.insertFront(e13);
      EdgeListNode node13 = (EdgeListNode) list1.front();
      node13.setPartner((EdgeListNode) list3.front());
      list2.insertFront(e23);
      list3.insertFront(e23);
      EdgeListNode node23 = (EdgeListNode) list2.front();
      node23.setPartner((EdgeListNode) list3.front());
      list3.insertFront(e33);
      EdgeListNode node33 = (EdgeListNode) list3.front();
      node33.setPartner(node33);
      list1.insertFront(e14);
      list1.insertFront(e15);
      System.out.println("Checking Insertions");
      System.out.println("Should be [ [[1, 5], 15] [[1, 4], 14] [[1, 3], 13] [[1, 2], 12] ]: " + list1);
      System.out.println("Should be [ [[2, 3] 23] [[1, 2], 12] ]: " + list2);
      System.out.println("Should be [ [[3, 3], 33] [[2, 3], 23] [[1, 3], 13] ]: " + list3);
      System.out.println("Checking Neighbors");
      Neighbors neighbor1 = list1.getNeighbors(new Integer(1));
      Neighbors neighbor2 = list2.getNeighbors(new Integer(2));
      Neighbors neighbor3 = list3.getNeighbors(new Integer(3));
      System.out.println("Should be [15, 14, 13, 12]: " +  
			 Arrays.toString(neighbor1.neighborList) + Arrays.toString(neighbor1.weightList));
      System.out.println("Should be [23, 12]: " + 
			 Arrays.toString(neighbor2.neighborList) + Arrays.toString(neighbor2.weightList));
      System.out.println("Should be [33, 23, 13]: " + 
			 Arrays.toString(neighbor3.neighborList) + Arrays.toString(neighbor3.weightList));
      System.out.println("Checking Removals");
      list1.front().next().remove();      
      System.out.println("Should be [ [[1, 5], 15] [[1, 3], 13] [[1, 2], 12] ]: " + list1);      
      System.out.println("Should be [ [[2, 3] 23] [[1, 2], 12] ]: " + list2);
      System.out.println("Should be [ [[3, 3], 33] [[2, 3], 23] [[1, 3], 13] ]: " + list3);
      list3.front().remove();
      System.out.println("Should be [ [[1, 5], 15] [[1, 3], 13] [[1, 2], 12] ]: " + list1);      
      System.out.println("Should be [ [[2, 3] 23] [[1, 2], 12] ]: " + list2);
      System.out.println("Should be [ [[2, 3], 23] [[1, 3], 13] ]: " + list3);
      list2.front().remove();
      System.out.println("Should be [ [[1, 5], 15] [[1, 3], 13] [[1, 2], 12] ]: " + list1);      
      System.out.println("Should be [ [[1, 2], 12] ]: " + list2);
      System.out.println("Should be [ [[1, 3], 13] ]: " + list3);
      System.out.println("Checking destroy");     
    } catch (InvalidNodeException ex) {
      ex.printStackTrace();
    }
  }
}


